package org.example.inventory.dao;


import org.example.inventory.entity.Product;
import org.example.inventory.exception.InsufficientStockException;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

public interface ProductDao {
    /**
     * @param product
     * @return 插入成功的product对象(这个包含主键id和创建时间)
     */
    Product insert(Product product);

    /**
     * 根据id查询产品信息
     *
     * @param id
     * @return 产品对象
     */
    Product selectProductById(Integer id);

    /**
     * 更新产品信息
     *
     * @param product 待更新的
     * @return 更新影响的行数
     */
    int updateProduct(Product product);

    /**
     * 根据id删除一个产品
     * @param id
     * @return 受影响的行数
     */
    int deleteProductById(Integer id);

    /**
     *分页查询产品列表-支持排序
     * @param pageNum 页码
     * @param pageSize 每页数量
     * @param sortField 排序字段
     * @param ascending 是否升序
     * @return 分页后的产品列表
     */
    List<Product> selectProductList(int pageNum, int pageSize, String sortField, boolean ascending);

    /**
     *条件动态查询(名称模糊匹配，价格区间，库存下限)
     * 下面为可选
     * @param nameKeyword 名称关键词
     * @param minPrice 最低价格
     * @param maxPrice 最高价格
     * @param minStock 最小库存
     * @return 符合条件的商品列表
     */
    List<Product> searchProducts(String nameKeyword, BigDecimal minPrice, BigDecimal maxPrice, Integer minStock);

    /**
     *增加/减少库存(原子操作)
     * @param productId 商品ID
     * @param deltaStock 库存变化(正数为增加，负数为减少)
     * @return 更新后的库存值
     * @throws InsufficientStockException 库存不足抛出
     */
    int updateStock(Integer productId, int deltaStock) throws InsufficientStockException;

    /**
     *获取低库存商品(库存低于阈值)
     * @param threshold 库存阈值
     * @return 低库存商品列表
     */
    List<Product> selectLowStockProducts(int threshold);

    /**统计与整合
     *统计商品总数
     * @return 商品总数
     */
    long countTotalProducts();

    /**
     *按价格区间统计商品数量
     * @param min 最低价
     * @param max 最高价
     * @return 商品数量
     */
    long countProductsInRangePrice(BigDecimal min, BigDecimal max);

    /**扩展操作
     *批量插入商品(用于初始化)
     * @param products 商品列表
     * @return 插入成功的数量
     */
    int batchInsertProducts(List<Product> products);

    /**
     *更新最后补货时间
     * @param productId 商品ID
     * @param restockTime 补货时间
     * @return 影响的行数
     */
    int updateLastRestockTime(Integer productId, LocalDateTime restockTime);


}
